/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Parser;

import lowlevel.Function;
import lowlevel.Operand;
import lowlevel.Operand.OperandType;
import lowlevel.Operation;
import lowlevel.Operation.OperationType;
import scanner.Token.TokenType;

/**
 *
 * @author maxmuhlenkamp
 */
public class BinaryExpression extends Expression{
    Expression leftSide;
    Expression rightSide;
    
    TokenType operator;
    
    public BinaryExpression(Expression leftSide, TokenType operator, Expression rightSide){
        this.leftSide = leftSide;
        this.operator = operator;
        this.rightSide = rightSide;
    }

    @Override
    void print(String indent) {
        CMinusParser.oFile.println(indent + "BinaryExpression:");
        switch(operator){
            case PLUS_TOKEN:
                CMinusParser.oFile.println(indent + "  +");
                break;
            case MINUS_TOKEN:
                CMinusParser.oFile.println(indent + "  -");
                break;
            case LTE_TOKEN:
                CMinusParser.oFile.println(indent + "  <=");
                break;
            case LT_TOKEN:
                CMinusParser.oFile.println(indent + "  <");
                break;
            case GT_TOKEN:
                CMinusParser.oFile.println(indent + "  >");
                break;
            case GTE_TOKEN:
                CMinusParser.oFile.println(indent + "  >=");
                break;
            case EQUALITY_TOKEN:
                CMinusParser.oFile.println(indent + "  ==");
                break;
            case NOT_EQUAL_TOKEN:
                CMinusParser.oFile.println(indent + "  !=");
                break;
            case MULT_TOKEN:
                CMinusParser.oFile.println(indent + "  *");
                break;
            case DIV_TOKEN:
                CMinusParser.oFile.println(indent + "  /");
                break;
            default:
                CMinusParser.oFile.println("APPARENTLY I MISSED A TOKEN TYPE IN BINARY EXPRESSION!");
        }
        leftSide.print(indent + "  ");
        rightSide.print(indent + "  ");
        CMinusParser.oFile.flush();
    }

    @Override
    public void genLLCode(Function func) {
        regNum = func.getNewRegNum();
        
        leftSide.genLLCode(func);
        rightSide.genLLCode(func);
        
        Operand leftOp = new Operand(OperandType.REGISTER, leftSide.getRegNum());
        Operand rightOp = new Operand(OperandType.REGISTER, rightSide.getRegNum());
        Operand destOp = new Operand(OperandType.REGISTER, regNum);
        
        OperationType type = null;
        switch(operator){
            case PLUS_TOKEN:
                type = OperationType.ADD_I;
                break;
            case MINUS_TOKEN:
                type = OperationType.SUB_I;
                break;
            case LTE_TOKEN:
                type = OperationType.LTE;
                break;
            case LT_TOKEN:
                type = OperationType.LT;
                break;
            case GT_TOKEN:
                type = OperationType.GT;
                break;
            case GTE_TOKEN:
                type = OperationType.GTE;
                break;
            case EQUALITY_TOKEN:
                type = OperationType.EQUAL;
                break;
            case NOT_EQUAL_TOKEN:
                type = OperationType.NOT_EQUAL;
                break;
            case MULT_TOKEN:
                type = OperationType.MUL_I;
                break;
            case DIV_TOKEN:
                type = OperationType.DIV_I;
                break;
            default:
                type = OperationType.UNKNOWN;
        }
        
        Operation op = new Operation(type, func.getCurrBlock());
        op.setDestOperand(0, destOp);
        op.setSrcOperand(0, leftOp);
        op.setSrcOperand(1, rightOp);
        
        func.getCurrBlock().appendOper(op);
    }
}
